//Name: Sara Thorup
#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"
#include <stdlib.h>
#include <time.h> 

/*
Random tester for the sea_hag card.  The sea_hag card discards the top deck card of each player (other than the current player) and replaces
it with a course card.

Things to randomize:
- number of players
- number of available curse cards
- deckcounts
*/
int getNumPlayers(int maxPlayers);
int getNumCurseCards(int maxCurseCards);
int setCurrentPlayersHand(struct gameState* gameState, int currentPlayer);
int* initalizePlayerDecks(struct gameState* gameState);
void testSeaHag();
void displayTestConditions(int numCurseCards, int numPlayers, struct gameState* gameState, int currentPlayer);
int getExpectedCurseCardCount(struct gameState* gameState, int currentPlayer, int numCurseCards);

int main(int argc, char *argv[]) {
	srand(time(NULL));
	int numTestRuns = 10000;
	//printf("Testing the sea_hag card.  How many tests would you like to run? \n");
	//printf("Enter an integer: \n");  
	//scanf ("%d", &numTestRuns);
	printf("Attempting %d test runs. Of the Sea_hag card \n", numTestRuns);

	int i = 0;
	for (; i < numTestRuns; i++) {
		printf("\nRun # %d \n", i);
		testSeaHag();
	}
	
	return 0;
}

int getNumPlayers(int maxPlayers) {
	int minPlayers = 2;
	int numPlayers = rand() % (maxPlayers + 1 - minPlayers) + minPlayers; 
	return numPlayers;
}

int getNumCurseCards(int maxCurseCards) {
	return rand() % (maxCurseCards + 1);
}

void displayTestConditions(int numCurseCards, int numPlayers, struct gameState* gameState, int currentPlayer) {
	printf("Test initialized with %d players and %d curse cards \n", numPlayers, numCurseCards);
	printf("Player %d is the current player \n", currentPlayer);
	int playerNumber = 0;
	for (; playerNumber < gameState->numPlayers; playerNumber++) {
		if (playerNumber != currentPlayer) {
			printf("Player %d started with %d cards in their deck\n", playerNumber, gameState->deckCount[playerNumber]);
		}
	}
	printf("\n");

}

void testSeaHag() {
	int maxCurseCards = 30;
	int numPlayers = getNumPlayers(MAX_PLAYERS); //MAX_PLAYERS is defined in dominion.h and is currently set to 4
	int numCurseCards = getNumCurseCards(maxCurseCards);
	int kingdomCards[10] = {adventurer, council_room, feast, gardens, mine, remodel, smithy, village, baron, great_hall};  
	struct gameState* gameState = newGame();
	int randomSeed = 100;
	if (initializeGame(numPlayers, kingdomCards, randomSeed, gameState) != 0){
		printf("Error initalizing game. \n");
		printf("Number of players = %d \n", numPlayers);
		return;
	}

	int* initalDeckCount = initalizePlayerDecks(gameState);
	gameState->supplyCount[curse] = numCurseCards;
	
	int currentPlayer = 0;
	int handPos = setCurrentPlayersHand(gameState, currentPlayer);

	
	gameState->whoseTurn = currentPlayer;

	displayTestConditions(numCurseCards, numPlayers, gameState, currentPlayer);
	
	int choice1 = 0;
	int choice2 = 0;
	int choice3 = 0;
	int bonus = 0;

	cardEffect(sea_hag, choice1, choice2, choice3, gameState, handPos, &bonus);

	//Check for errors
	if (numCurseCards < numPlayers - 1) { //-1 for the current player who does not get curse card
		printf("Warning: Not enough curse cards for all players. \n");
	}

	if (gameState->supplyCount[curse] != getExpectedCurseCardCount(gameState, currentPlayer, numCurseCards)) {
		printf("Error: Curse count supply was not correctly adjusted.  Expected %d remaining curse cards, not %d curse cards \n", getExpectedCurseCardCount(gameState, currentPlayer, numCurseCards), gameState->supplyCount[curse]);
	}
	int playerNumber = 0;
	for (; playerNumber < numPlayers; playerNumber++) {
		if (playerNumber != currentPlayer) {
			if (initalDeckCount[playerNumber] <= 0) {
				printf("Warning: Player %d had an empty deck and should not have been able to discard.  Current deckCount is now %d \n", playerNumber, gameState->deckCount[playerNumber]);
			}
		}
		
	}

	//when you run out of curse cards, the remaining players should not have a curse card.  if their deck count is > 0 then count should decrmenent
	//if there are curse cards and deck count is  > 0 then the count should stay the same.  other wise it should increase by 1

	if (numCurseCards < numPlayers - 1) {
		playerNumber = 0;
		for (; playerNumber < numPlayers; playerNumber++) {
			if (playerNumber != currentPlayer) {
				if (playerNumber <= numCurseCards) {
					//top deck card should be a curse card
					if (gameState->deck[playerNumber][gameState->deckCount[playerNumber] - 1] != curse) {
						printf("Error: Player %d did not receive a curse card \n", playerNumber);
					}
					if (initalDeckCount[playerNumber > 0 ]) {
						if (initalDeckCount[playerNumber] != gameState->deckCount[playerNumber]) {
							printf("Error: DeckCount for player %d was incorrectly adjusted \n", playerNumber);
						}
					} else if (initalDeckCount[playerNumber] + 1 != gameState->deckCount[playerNumber]) {
							printf("Error: DeckCount for player %d was incorrectly adjusted \n", playerNumber);
						}
					}

				else {
					if (gameState->deck[playerNumber][gameState->deckCount[playerNumber] - 1] == curse) {
						printf("Error: Player %d received a curse card when none were available \n", playerNumber);
					}
					if (initalDeckCount[playerNumber > 0 ]) {
						if (initalDeckCount[playerNumber] - 1 != gameState->deckCount[playerNumber]) {
							printf("Error: DeckCount for player %d was incorrectly adjusted \n", playerNumber);
						}
					}
				}
			}
		}

	} else {
		playerNumber = 0;
		for (; playerNumber < numPlayers; playerNumber++) {
			if (playerNumber != currentPlayer) {
				//top deck card should be a curse card
				if (gameState->deck[playerNumber][gameState->deckCount[playerNumber] - 1] != curse) {
					printf("Error: Player %d did not receive a curse card \n", playerNumber);
				}
				if (initalDeckCount[playerNumber > 0 ]) {
					if (initalDeckCount[playerNumber] != gameState->deckCount[playerNumber]) {
						printf("Error: DeckCount for player %d was incorrectly adjusted \n", playerNumber);
					}
				} else if (initalDeckCount[playerNumber] + 1 != gameState->deckCount[playerNumber]) {
						printf("Error: DeckCount for player %d was incorrectly adjusted \n", playerNumber);
				}
			
			}
		}
	}
	

}

int getExpectedCurseCardCount(struct gameState* gameState, int currentPlayer, int numCurseCards) {
	int playerNumber = 0;
	int expectedCurseCount = numCurseCards;
	for (; playerNumber < gameState->numPlayers; playerNumber++) {
		if (playerNumber != currentPlayer) { //exclude current player since he/she would not have gotten a curse card
			if (expectedCurseCount > 0) {
				expectedCurseCount--;
			}
		}
	}
	return expectedCurseCount;
}

int setCurrentPlayersHand(struct gameState* gameState, int currentPlayer) {
	//We want the currentPlayer's hand to have the curse card
	int handCount = 10;
	int defaultCard = estate;
	int handPos = 0;
	int cardNumber = 0;
	gameState->handCount[currentPlayer] = handCount;

	gameState->hand[currentPlayer][cardNumber] = curse;
	cardNumber++;

	for (; cardNumber < handCount; cardNumber++) {
		gameState->hand[currentPlayer][cardNumber] = defaultCard;
	}

	return handPos;
}

int* initalizePlayerDecks(struct gameState* gameState) {
	int playerNumber = 0;
	int cardNumber = 0;
	int deckCount = 0;
	int maxDeckCount = 10;
	int defaultCard = estate;
	int* initalDeckCount = malloc(sizeof(int) * gameState->numPlayers);

	//For each player, choose a random deckcount.  Fill deck with default card type
	for ( ; playerNumber < gameState->numPlayers; playerNumber++) {
		deckCount = rand() % maxDeckCount;
		gameState->deckCount[playerNumber] = deckCount;
		initalDeckCount[playerNumber] = deckCount;


		for ( ; cardNumber < deckCount; cardNumber++) {
			gameState->deck[playerNumber][cardNumber] = defaultCard;
		}
	}

	return initalDeckCount;
}



